#include "TTimer.h"
#include <QDebug>

TTimer::TTimer(size_t interval, bool isRepeat): _expired(true), _try_to_expire(false)
  ,m_interval(interval),m_isRepeat(isRepeat)
{
}

TTimer::~TTimer()
{
    stop();
}

void TTimer::start(std::function<void()> task)
{
    if (m_isRepeat) {
        // is started, do not start again
        if (_expired == false)
            return;

        // start async timer, launch thread and wait in that thread
        _expired = false;
        std::thread([this, task]() {
            while (!_try_to_expire)
            {
                // sleep every interval and do the task again and again until times up
                std::this_thread::sleep_for(std::chrono::milliseconds(m_interval));
                task();
            }

            {
                // timer be stopped, update the condition variable expired and wake main thread
                std::lock_guard<std::mutex> locker(_mutex);
                _expired = true;
                _expired_cond.notify_one();
            }
        }).detach();
    } else {
        std::thread([this, task]() {
            std::this_thread::sleep_for(std::chrono::milliseconds(m_interval));
            task();
            this->_expired.store(true);
        }).detach();
    }
}

void TTimer::stop()
{
    // do not stop again
    if (_expired)
        return;

    if (_try_to_expire)
        return;

    // wait until timer
    _try_to_expire = true; // change this bool value to make timer while loop stop
    {
        std::unique_lock<std::mutex> locker(_mutex);
        _expired_cond.wait(locker, [this] {return _expired == true; });

        // reset the timer
        if (_expired == true)
            _try_to_expire = false;
    }
}

bool TTimer::isExpired()
{
    return _expired;
}

